package org.hjl.commonutils.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * 时间格式转换
 *
 * @author hjl
 */
public class DateUtil {
    public static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static DateTimeFormatter formatterMillisecond = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS");
    static SimpleDateFormat specificDate = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 系统时间
     */
    public static Date nowDate() {
        return new Date();
    }

    /**
     * 系统时间
     */
    public static String systemTimeByString() {
        return specificDate.format(new Date());
    }

    /**
     * 当前星期
     */
    public static String currentWeek() {
        return dateToWeek(systemTimeByString());
    }

    /**
     * 根据日期获取 星期
     */
    public static String dateToWeek(String datetime) {
        String[] weekDays = {"7", "1", "2", "3", "4", "5", "6"};
        Calendar cal = Calendar.getInstance();
        Date date;
        try {
            date = specificDate.parse(datetime);
            cal.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return "";
        }
        //一周的第几天
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    /**
     * 获取默认下周及指定周期的指定天数
     */
    public static String getAppointMonDate(int week, int day, LocalDate localDate) {
        LocalDate nextMonDate = null;

        for (int i = 0; i < week; i++) {

            if (nextMonDate == null) {
                nextMonDate = getNextMonDate(localDate);
            } else {
                nextMonDate = nextMonDate.plusDays(7);
            }
        }

        return localDateToString(nextMonDate.plusDays(day));
    }

    public static LocalDate getNextMonDate(LocalDate localDate) {
        LocalDate with = null;

        with = localDate.with(ChronoField.DAY_OF_WEEK, 7L);

        return with;
    }

    public static String localDateToString(LocalDate formatDate) {
        return formatDate.format(dateTimeFormatter);
    }

    public static String localDateTimeToString(LocalDateTime formatDate) {
        return formatDate.format(formatter);
    }

    public static String localDateTimeSssToString(LocalDateTime formatDate) {
        return formatDate.format(formatterMillisecond);
    }

    /**
     * 获取月的第一天
     *
     * @param month 月
     */
    public static String getMonthBeginDate(String month) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, Integer.parseInt(month) - 1);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return sdf.format(c.getTime());
    }

    /**
     * 获取月的最后一天
     *
     * @param month 月
     */
    public static String getMonthEndDate(String month) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, Integer.parseInt(month) - 1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return sdf.format(c.getTime());
    }

    public static boolean isBetween(String beginTime, String endTime) {
        //获取当前时间
        LocalTime now = LocalTime.now();
        boolean flag = false;
        if (now.isAfter(stringToLocalTime(beginTime)) && now.isBefore(stringToLocalTime(endTime))) {
            flag = true;
        }
        return flag;
    }

    /**
     * 字符串转换为LocalDateTime
     */
    public static LocalDateTime stringToLocalDateTime(String time) {
        //1.具有转换功能的对象
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        return LocalDateTime.parse(time, df);
    }

    /**
     * 时间区间
     * 1号区间：上月21号-月底最后一天的订单
     * 11号区间：当月1号-10号的订单
     * 21号区间：当月11号-20号的订单
     */
    public static Map<String, String> timeInterval(LocalDate now) {
        Map<String, String> timeInterval = new HashMap<>();
        int dayOfMonth = now.getDayOfMonth();
        if (1 <= dayOfMonth && dayOfMonth <= 10) {
            String startDate = DateUtil.getMonthBeginDate(String.valueOf(now.getMonthValue()));
            LocalDate endDate = DateUtil.stringToLocalDate(startDate).plusDays(+9);
            timeInterval.put("startDate", startDate);
            timeInterval.put("endDate", DateUtil.localDateToString(endDate));
            return timeInterval;
        }
        if (11 <= dayOfMonth && dayOfMonth <= 20) {
            String firstDay = DateUtil.getMonthBeginDate(String.valueOf(now.getMonthValue()));
            LocalDate startDate = DateUtil.stringToLocalDate(firstDay).plusDays(+10);
            LocalDate endDate = DateUtil.stringToLocalDate(firstDay).plusDays(+19);
            timeInterval.put("startDate", DateUtil.localDateToString(startDate));
            timeInterval.put("endDate", DateUtil.localDateToString(endDate));
            return timeInterval;
        }
        String firstDay = DateUtil.getMonthBeginDate(String.valueOf(now.getMonthValue()));
        LocalDate startDate = DateUtil.stringToLocalDate(firstDay).plusDays(+20);
        String endDate = DateUtil.getMonthEndDate(String.valueOf(now.getMonthValue()));
        timeInterval.put("startDate", DateUtil.localDateToString(startDate));
        timeInterval.put("endDate", endDate);
        return timeInterval;
    }

    /**
     * 字符串转换为LocalDate
     */
    public static LocalDate stringToLocalDate(String time) {
        //1.具有转换功能的对象
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return LocalDate.parse(time, df);
    }

    /**
     * 字符串转换为LocalTime
     */
    public static LocalTime stringToLocalTime(String time) {
        //1.具有转换功能的对象
        DateTimeFormatter df = DateTimeFormatter.ofPattern("HH:mm:ss");
        return LocalTime.parse(time, df);
    }


    public static Calendar getCalendar(LocalDate time) {
        Calendar calendar = Calendar.getInstance();
        // 设置年
        calendar.set(Calendar.YEAR, time.getYear());
        // 设置月
        calendar.set(Calendar.MONTH, time.getMonthValue());
        // 设置日
        calendar.set(Calendar.DATE, time.getDayOfMonth());
        return calendar;
    }

    /**
     * 两个日期之间的日期
     */
    public static List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
        List<LocalDate> dates = new ArrayList<>();
        long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate);
        for (int i = 0; i <= numOfDaysBetween; i++) {
            LocalDate date = startDate.plusDays(i);
            dates.add(date);
        }
        return dates;
    }

    /**
     * 比较第一个日期是否小于第二个日期
     *
     * @param firstDate  第一个日期
     * @param secondDate 第二个日期
     * @return true-小于;false-大于
     */
    public static boolean localDateIsBefore(LocalDate firstDate, LocalDate secondDate) {
        return firstDate.isBefore(secondDate);
    }

    /**
     * 比较第一个日期是否小于第二个日期
     *
     * @param firstDate  第一个日期
     * @param secondDate 第二个日期
     * @return true-小于;false-大于
     */
    public static boolean localDateIsBefore(LocalDateTime firstDate, LocalDateTime secondDate) {
        return firstDate.isBefore(secondDate);
    }

    /**
     * 比较第一个日期是否大于第二个日期
     *
     * @param firstDate  第一个日期
     * @param secondDate 第二个日期
     * @return true-大于;false-不大于
     */
    public static boolean localDateIsAfter(LocalDate firstDate, LocalDate secondDate) {
        return firstDate.isAfter(secondDate);
    }

    /**
     * 比较两个日期是否相等
     *
     * @param firstDate  第一个日期
     * @param secondDate 第二个日期
     * @return true-相等;false-不相等
     */
    public static boolean localDateIsEqual(LocalDate firstDate, LocalDate secondDate) {
        return firstDate.isEqual(secondDate);
    }

}
